
using System;
using System.Collections.Generic;
using DG.Tweening;
using M0;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AI;

namespace M1
{
    public class 人 : MonoBehaviour,I可点击,I碰撞
    {
        [SerializeField] public 摄像机跟随 ft;
        [SerializeField] private int Id;
        [Header("名片设置")] [SerializeField] private string name;
        [SerializeField] private string 名片地址;
        [SerializeField] private int 名片层级;
        [SerializeField] private bool 主角;
        [SerializeField] private Vector3 名片偏移;
        [SerializeField] public Transform 摄像机点1;
        [SerializeField] public Transform 摄像机点2;
        [SerializeField] public NavMeshAgent 寻路;
        [SerializeField] public float velocity=5;
        [SerializeField] public float turnSpeed=10;
        
        
        [SerializeField] public SkinnedMeshRenderer 头发皮肤;
        [SerializeField] public SkinnedMeshRenderer 上衣皮肤;
        [SerializeField] public SkinnedMeshRenderer 裤子皮肤;
        [SerializeField] public List<GameObject> 装饰;


        private void OnMouseUp()
        {
            M.Event.DoEvent<int>(M.EventKey_点击人,Id);
        }

        public void 开启任务标识()
        {
            if (m名片 != null)
            {
                m名片.开始任务标识();
            }
        }

        public void Show名片(bool b)
        {
            if (m名片 != null)
            {
                m名片.Enable = b;
                m名片.隐藏所有标识();
            }
        }
        [SerializeField]private 名片 m名片;
        private 移动输入 输入;
        private bool 摇杆输入中;

        [ContextMenu("寻路")]
        public void Test寻路()
        {
            AI寻路(new Vector3(0, 0, 0));
        }

        public bool 寻路中 = false;
        private Vector3 寻路目的地;
        private Action 寻路回调;
        private Vector3 寻路坐标;
        public void 重设寻路点()
        {
            // if (transform.position != 寻路坐标)
            // {
            //     AI寻路(transform.position);
            // }
        }
        public void AI寻路(Vector3 v3,Action callBack=null)
        {
            // if (寻路坐标 == v3)
            // {
            //     v3= Vector3.zero;
            // }
            寻路坐标 = v3;
            Debug.Log("目的地+"+v3);
            // 寻路.isStopped = false;
            寻路目的地 = v3;
            寻路.isStopped = false;
            寻路.SetDestination(v3);
            寻路中 = true;
            transform.GetComponent<Animator>().SetBool("Run", true);
            寻路回调 = callBack;
        }

        public void 取消寻路()
        {
            寻路中 = false;
            寻路回调 = null;
            寻路.isStopped = true;
        }


        public void 转身(Quaternion rot)
        {
            输入.targetRotation = rot;
        }
        public void 控制输入(Vector2 v2)
        {
            输入.输入(v2,ft.跟随模式);
            摇杆输入中 = true;
        }

        /// <summary>
        /// 名字
        /// </summary>
        /// <param name="n"></param>
        public void SetName(string n)
        {
            name = n;
            if (!string.IsNullOrEmpty(name))
            {
                if (m名片 == null)
                {
                    m名片 = M.Resource.Load<名片>(名片地址);
                    var layer = M.MWin.GetLayer(名片层级);
                    m名片.transform.SetParent(layer.transform, false);
                }

                m名片.setName(name, 主角);
            }
        }

        public string GetName()
        {
            return name;
        }

        /// <summary>
        /// 等级
        /// </summary>
        /// <param name="uLevel"></param>
        public void SetId(int id)
        {
            Id= id;
        }

        public int GetId()
        {
            return Id;
        }




        [ContextMenu("测试位移")]
        public void Test()
        {
            var 主角 = GameObject.FindWithTag("Player");
            主角.transform.localPosition = new Vector3(-10.2f,-5.96f,-11.58f);
            float y = 90f;
            主角.transform.localEulerAngles = new Vector3(0, y, 0);
        }



        private void Update()
        {
            if (!摇杆输入中)
            {
                float x = Input.GetAxisRaw("Horizontal");
                float y = Input.GetAxisRaw("Vertical");
                输入.输入(new Vector2(x, y),ft.跟随模式);
            }

            摇杆输入中 = false;
            // 输入.判断运动状态();
            名片跟随();

            if (寻路中)
            {
                float distance = Vector3.Distance(transform.position, 寻路目的地);
                if (distance <= 寻路.stoppingDistance)
                {
                    寻路完成();
                }
            }
        }

        private void 寻路完成()
        {
            Debug.Log("寻路完成！！！！");
            transform.GetComponent<Animator>().SetBool("Run", false);
            寻路回调?.Invoke();
            取消寻路();
        }

        private void 名片跟随()
        {
            if (m名片 != null)
            {
                Vector3 v3 = transform.position;
                // if (Id != -1)
                // {
                //     var p = GameObject.FindWithTag("Player");
                //     v3 = v3 - p.transform.position;
                // }

                m名片.跟随(v3);
            }
        }

        private void OnCollisionEnter(Collision other)
        {
            // Debug.Log(other.collider.gameObject.name);
            var I碰 = other.collider.gameObject.GetComponent<I碰撞>();
            if (I碰 != null)
            {
                I碰.碰撞触发(Id);
            }
        }
        public void 碰撞触发(int id)
        {
            if (id > -1)
            {
                M.Event.DoEvent(M.EventKey_碰撞,id);
            }
        }

        private void Awake()
        {
            if (ft == null)
            {
                ft = GameObject.FindObjectOfType<摄像机跟随>();
            }

            if (ft == null)
            {
                BDebug.Error("没找到 摄像机跟随 ！！！！");
            }

            输入 = new 移动输入(transform, ft,velocity,turnSpeed);

            // SetName("我的电脑");
        }


        public void 删除()
        {
            if (Application.isPlaying)
            {
                if (this != null)
                {
                    Destroy(gameObject);
                }
                if (m名片 != null)
                {
                    GameObject.Destroy(m名片.gameObject);
                }
            }
        }

        public void 选头发(Material dataMat)
        {
            头发皮肤.material = dataMat;
        }
        public void 选上衣(Material dataMat)
        {
            上衣皮肤.material = dataMat;
        }
        public void 选裤子(Material dataMat)
        {
            裤子皮肤.material = dataMat;
        }

        public void 选装饰(int dataIndex, int next)
        {
            装饰[dataIndex].gameObject.SetActive(next==1);
        }


        public void SetUp(Material 左头发, Material 左上衣, Material 左裤子, List<int> 左装饰详情)
        {
            选头发(左头发);
            选上衣(左上衣);
            选裤子(左裤子);
            for (int i = 0; i < 左装饰详情.Count; i++)
            {
                选装饰(i, 左装饰详情[i]);
            }
        }

        public void Play表情(string s)
        {
            Animator ani = transform.GetComponent<Animator>();
            ani.Play(s);
        }

        public void 指定移动(Vector3 pos2,float time,Action 回调)
        {
            var ani = transform.GetComponent<Animator>();//.SetBool("Run", true);
            ani.SetBool("Walk",true);
            var dot = transform.DOMove(pos2, time);
            dot.OnComplete(() =>
            {
                回调?.Invoke();
                ani.SetBool("Walk",true);
            });
        }



    }

    public enum 人类状态
    {
        休息,
        Run,
    }

    public class 移动输入
    {
        private 人类状态 curState;

        private 人类状态 Set状态
        {
            get { return curState; }
            set
            {
                if (curState != value)
                {
                    curState = value;
                    处理状态(value);
                }
            }
        }

        private void 处理状态(人类状态 state)
        {
            switch (state)
            {
                case 人类状态.休息:
                    身体动画.SetBool("Run", false);
                    comp人.重设寻路点();
                    break;
                case 人类状态.Run:
                    身体动画.SetBool("Run", true);
                    break;
            }
        }


        private Transform 身体;
        private Animator 身体动画;

        private float velocity = 5;
        private float turnSpeed = 10;
        private 摄像机跟随 摄像机跟随;
        private 人 comp人;

        public 移动输入(Transform tran, 摄像机跟随 跟随, float 速度 = 5f, float 转速度 = 10f)
        {
            身体 = tran;
            身体动画 = 身体.GetComponent<Animator>();
            comp人 = 身体.GetComponent<人>();
            velocity = 速度;
            turnSpeed = 转速度;
            摄像机跟随 = 跟随;
        }

        private Vector2 curInput;
        private float angle;
        public Quaternion targetRotation;

        public void 输入(Vector2 input,相机跟随模式 type)
        {
            curInput = input;
            if (!判断运动状态())
            {
                return;
            }

            if (comp人.寻路中)
            {
                comp人.取消寻路();
            }

            计算角度(type);
            Rotate();
            Move();
        }

        public bool 判断运动状态()
        {
            if (Mathf.Abs(curInput.x) < 0.1f && Mathf.Abs(curInput.y) < 0.1f)
            {
                Set状态 = 人类状态.休息;
                return false;
            }
            else
            {
                Set状态 = 人类状态.Run;
                return true;
            }
        }

        void 计算角度(相机跟随模式 type)
        {
            angle = Mathf.Atan2(curInput.x, curInput.y);
            angle = Mathf.Rad2Deg * angle;
            if (type == 相机跟随模式.第三人称)
            {
                angle += 摄像机跟随.transform.eulerAngles.y;
            }
        }

        void Rotate()
        {
            if (摄像机跟随 != null && 摄像机跟随.camRotation)
            {
                身体.rotation = Quaternion.Euler(0, curInput.x * 1.5f, 0) * 身体.rotation;
            }
            else
            {
                targetRotation = Quaternion.Euler(0, angle, 0);
            }

            身体.rotation = Quaternion.Slerp(身体.rotation, targetRotation, turnSpeed * Time.deltaTime);
        }

        void Move()
        {
            身体.position += 身体.forward * velocity * Time.deltaTime;
        }
    }
}
